今天來完成剩下的兩個事件 新增 和 編輯
首先先來處理 新增 的部分,先調整模板
主要處理的部分有
+ 按鈕在最下方edit 狀態來記錄id 為空時,代表為新增<t t-name="todoList">
    <table>
        <tbody>
            <t t-if="items.length">
                <tr t-foreach="items" t-as="item">
                    <td>
                        <input type="checkbox"
                               class="finished"
                               t-att-checked="item.finished ? 'checked' : undefined"
                               t-att-data-index="item_index"/>
                    </td>
                    <td>
                        <div t-if="!item.edit" t-esc="item.name" 
														 t-att-data-index="item_index" class="todo-name"/>
                        <input t-else=""
                               type="text" class="todo-name-input"
                               t-att-value="item.name"/>
                    </td>
                    <td>
                        <i t-attf-class="fa fa-{{ item.edit ? 'check' : 'times' }}"
                           t-att-data-index="item_index"/>
                    </td>
                </tr>
            </t>
            <tr t-else="">
                <td colspan="3">
                    <span class="alert alert-success">無任何的待辦事項</span>
                </td>
            </tr>
            <tr>
                <td colspan="3" class="pt-3">
                    <button type="button" class="btn btn-info w-100 text-center btn-new-todo">
                        <i class="fa fa-plus"/>
                    </button>
                </td>
            </tr>
        </tbody>
    </table>
</t>
接著調整 JS 的部分,增加兩個事件
'click .btn-new-todo': '_newItem',
'click i.fa-check': '_saveItem',
加入對應的函式
_newItem: function () {
    let alreadyHaveNewOne = !!this.todoList.filter(item => !item.id).length;
    if (alreadyHaveNewOne) {
        return true;
    }
    this.todoList.push({id: null, name: '', finished: false, edit: true});
    this.renderElement();
    this.el.querySelector('.todo-name-input').focus();
},
_saveItem: function (ev) {
    const self = this;
    let target = ev.currentTarget,
        data_index = target.dataset.index;
    if (!data_index) {
        return true;
    }
    let index = parseInt(data_index);
    let data = this.todoList.at(index);
    if (!data) {
        return true;
    }
    Object.assign(data, {
        name: this.el.querySelector(`input.todo-name-input`).value,
        finished: this.el.querySelector(`input[type='checkbox'][data-index="${index}"]`).checked,
    })
    this._rpc({
        model: 'todo.list',
        method: 'create',
        args: [{
            name: data.name,
            finished: data.finished,
        }]
    }).then(result => {
        if (result) {
            data.id = result;
            data.edit = false;
            self.renderElement();
        }
    });
},
新增 就完成了,是不是很簡單呢
接下來 編輯的部份,因為在新增的時候就有先把模板先改好了,就是 [item.name](http://item.name) 的部分
<div t-if="!item.edit" t-esc="item.name" 
		 t-att-data-index="item_index" class="todo-name"/>
所以接下來要調整一下 JS
一樣增加對應的事件
'click .todo-name': '_editItem',
增加對應的函式
_editItem: function (ev) {
    let target = ev.currentTarget,
        data_index = target.dataset.index;
    if (!data_index) {
        return true;
    }
    let index = parseInt(data_index);
    let data = this.todoList.at(index);
    if (!data) {
        return true;
    }
    if (!data.edit) {
        this.todoList.forEach(item => {
            if (item.edit) {
                item.edit = false;
            }
        });
        data.edit = true;
        this.renderElement();
        this.el.querySelector('.todo-name-input').focus();
    }
},
完成後重新整理網頁測試一下
咦? 編輯存檔後還是新增耶
是的,所以要調整一下 _saveItem() ,要增加判斷 id 是否為空,為空就是新增,反之則更新
_saveItem: function (ev) {
    const self = this;
    let target = ev.currentTarget,
        data_index = target.dataset.index;
    if (!data_index) {
        return true;
    }
    let index = parseInt(data_index);
    let data = this.todoList.at(index);
    if (!data) {
        return true;
    }
    let updateData = {
        name: this.el.querySelector(`input.todo-name-input`).value,
        finished: this.el.querySelector(`input[type='checkbox'][data-index="${index}"]`).checked,
    };
    Object.assign(data, updateData);
    if (data.id) {
        this._rpc({
            model: 'todo.list',
            method: 'write',
            args: [[data.id], updateData]
        }).then(result => {
            if (result) {
                data.edit = false;
                self.renderElement();
            }
        });
    } else {
        this._rpc({
            model: 'todo.list',
            method: 'create',
            args: [updateData]
        }).then(result => {
            if (result) {
                data.id = result;
                data.edit = false;
                self.renderElement();
            }
        });
    }
},
再次重新整理網頁測試後就正常了
當然我寫的程式有很多地方可以更精簡,就讓有興趣各位自行拆分職責了
最後有個小作業, _toggleFinish() 有一個很明顯的 BUG,
各位可以找一下在哪邊
Hint: 當資料為新增時,點完成會發生什麼事呢?